﻿using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using NLog.Fluent;
using System.Diagnostics;
using System.IO;
using System.Text;
using System.Threading.Tasks;
using System;
using XfTechOAWeb.EFCore;
using XfTechOAWeb.Models;
using System.Linq;
using XfTechOAWeb.Dtos;
using Jose;

namespace XfTechOAWeb.ApiServer.Middlewares
{
    public class LogsMiddleware
    {
        private readonly RequestDelegate _next;
        ILogger<LogsMiddleware> _logger;
        SqlServerDbContext _SqlServerDbContext;
        public LogsMiddleware(RequestDelegate next, ILogger<LogsMiddleware> logger, SqlServerDbContext sqlServerDbContext)
        {
            _SqlServerDbContext = sqlServerDbContext;
            _logger = logger;
            _next = next;

        }
        /// <summary>
        /// 编辑日志
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        public async Task Invoke(HttpContext context)
        {


            LogMessage log = new LogMessage();


            #region   记录请求的信息
            string Way = context.Request.Method;//请求方式
            string Site = context.Request.Path;//请求地址
            string requestUrl = context.Request.Path;//请求方法路径(Api/控制器/方法)
            log.WayToRequest = Way;//添加请求方式
            log.Site = Site;//添加请求地址
            var Temporary = requestUrl.Split("/");
            var Controller = "";
            var Method = "";
            if (Temporary[1] != "swagger")
            {
                Controller = Temporary[1] + "=》" + Temporary[2];//执行的控制器
                Method = Temporary[3];//执行的方法
            }
            else
            {
                Controller = Temporary[1];//记录Swagger
                Method = Temporary[2];//Swagger
            }
            log.MethodName = Method;//添加日志方法
            log.OperationClass = Controller;//添加日志控制器 


            #endregion

            #region 记录用户信息
            if (context.User.Identity.IsAuthenticated)  //判断是否验证
            {
                #region  查看context请求
                //Stream stream = context.Response.Body;//请求身体部分
                //var stream2 = context.Response.Headers;//请求头;
                //System.Console.WriteLine($"身体{stream}");//控制器输出请求身体
                //System.Console.WriteLine($"头部{stream2}");//控制器输出请求头
                string json = Newtonsoft.Json.JsonConvert.SerializeObject(context.Request.Headers, Newtonsoft.Json.Formatting.Indented);//查看请求头里面全部的数据
                System.Console.WriteLine($"请求头{json}");//控制器打印出来

                #endregion

                #region   方法一 用context通过请求头jwt令牌获取信息,取到的数据只有用户的
                var stream1 = context.Response.Headers["Authorization"].FirstOrDefault();//获取请求头部中的Jwt令牌
                System.Console.WriteLine($"{stream1}");
                if (stream1 != null)
                {
                    var data = stream1;//.Split(' ')[1];//去掉开头的Bearer没有就不用加
                    System.Console.WriteLine($"jwt:{data}");
                    var token = Jose.JWT.Decode(
                        data,
                        Encoding.UTF8.GetBytes("Wxf@q11231231231231q"),
                        JweAlgorithm.PBES2_HS256_A128KW,
                        JweEncryption.A128CBC_HS256,
                        null
                        );
                    //   JwtUserDto Jwtdata = Newtonsoft.Json.JsonConvert.DeserializeObject<JwtUserDto>(token);//自己定义一个表反序列化进去 
                }
                #endregion

                //#region  方法二 直接读取Jwt中间件保存的数据，较全面
                //System.Console.WriteLine($"用户名{context.User.FindFirst("LoginName").Value}");
                //log.UserName = context.User.FindFirst("LoginName").Value;

                //#endregion
            }
            else
            {
                #region  没登录的时候登录方法,注册方法只获取当前用户


                if (Method == "userregister")
                {
                    context.Request.EnableBuffering();
                    Stream stream = context.Request.Body;
                    Encoding encoding = Encoding.UTF8;
                    string date = string.Empty;
                    using (StreamReader reader = new StreamReader(stream, encoding, true, 1024, true))
                    {

                        date = Newtonsoft.Json.JsonConvert.DeserializeObject<UserLoginRequestDto>(reader.ReadToEndAsync().Result).Name;
                        log.UserName = date;
                        context.Request.Body.Position = 0;
                    }


                }
                #endregion
            }

            #endregion
            #region   计时器,记录运行时长
            Stopwatch stopwatch = new Stopwatch();

            stopwatch.Start();
            await _next(context);
            stopwatch.Stop();
            log.OperationConsume = stopwatch.ElapsedMilliseconds.ToString() + "毫秒";//运行耗时
            #endregion

            log.GeneratedTime = DateTime.Now;//生成日志时间
            //_SqlServerDbContext.LogMessages.Add(log);
            //_SqlServerDbContext.SaveChanges();

        }






    }
}
